package com.tianzmp.ttq.admin.service.impl;

import cn.hutool.Hutool;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.common.collect.Lists;
import com.tianzmp.ttq.admin.controller.resDto.MenuTree;
import com.tianzmp.ttq.admin.entity.*;
import com.tianzmp.ttq.admin.exception.AdminBusinessException;
import com.tianzmp.ttq.admin.mapper.MenuMapper;
import com.tianzmp.ttq.admin.mapper.RoleMapper;
import com.tianzmp.ttq.admin.mapper.RoleMenuMapper;
import com.tianzmp.ttq.admin.service.IRoleMenuService;
import com.tianzmp.ttq.admin.service.IRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author ttq
 * @since 2022-07-30
 */
@Service
public class RoleServiceImpl implements IRoleService {

    @Autowired
    private RoleMapper dao;

    @Autowired
    private IRoleMenuService roleMenuService;

    @Autowired
    private MenuMapper menuDao;


    @Autowired
    private RoleMenuMapper roleMenuDao;


    @Override
    public List<Role> list() {
        return dao.selectList(null);
    }

    @Override
    public PageInfo<List<Role>> pageList(Integer current, Integer size) {
        IPage<Role> page =  new Page<Role>(current,size);
        IPage<Role> result = dao.selectPage(page, null);
        return new PageInfo<List<Role>>(current,size, result.getTotal(), result.getRecords());
    }

    @Override
    public boolean insert(Role role) {
        return dao.insert(role) > 0;
    }

    @Override
    public boolean update(Role role) {
        return dao.updateById(role) > 0;
    }

    @Override
    public Role getById(Long id) {
        return dao.selectById(id);
    }

    @Override
    public boolean delete(List<Long> roleId) {
        return dao.deleteBatchIds(roleId) > 0 ;
    }

    @Transactional(rollbackFor = AdminBusinessException.class,readOnly = false)
    @Override
    public void authorMenu(Long roleId, List<Long> menus) {

        //1:delete
        LambdaQueryWrapper<RoleMenu> eq = new QueryWrapper<RoleMenu>().lambda().eq(RoleMenu::getRoleId, roleId);
        roleMenuService.remove(eq);

        //2:add
        assert menus != null;
        List<RoleMenu> collect = menus.stream().map(o -> {
            RoleMenu menu = new RoleMenu();
            menu.setRoleId(roleId);
            menu.setMenuId(o);
            return menu;
        }).collect(Collectors.toList());
        boolean b = roleMenuService.saveBatch(collect);
        if (!b){
            throw new AdminBusinessException(400,"角色赋值权限异常");
        }
    }

    @Override
    public List<MenuTree> rolePerssions(Long roleId) {

        //通过角色id获取菜单
        List<Menu> menus = menuDao.selectList(new QueryWrapper<Menu>().lambda().eq(Menu::getMenuStatus,1));
        if (null == menus || menus.size() == 0){
            return Lists.newArrayList();
        }

        //橘色拥有哪些权限
        LambdaQueryWrapper<RoleMenu> roleMenuQueryWrapper = new QueryWrapper<RoleMenu>().lambda();
        roleMenuQueryWrapper.eq(RoleMenu::getRoleId,roleId);
        List<RoleMenu> roleMenus = roleMenuDao.selectList(roleMenuQueryWrapper);
        Map<Long, Long> mapMenus = new HashMap<>(16);
        if (null != roleMenus && roleMenus.size() >0){
            mapMenus = roleMenus.stream().collect(Collectors.toMap(RoleMenu::getMenuId, RoleMenu::getRoleId, (k1, k2) -> k1));
        }
        Map<Long, Long> finalMapMenus = mapMenus;


        return  menus.stream().filter(o->o.getParentId().equals(0L)).map(o->{
            MenuTree menuTree = new MenuTree();
            menuTree.setId(o.getMenuId());
            menuTree.setPid(o.getParentId());
            menuTree.setUrl(o.getUrl());
            menuTree.setName(o.getMenuName());
            menuTree.setBtoType(o.getType());
            menuTree.setChecked(finalMapMenus.get(o.getMenuId()) != null);
            menuTree.setChild(getChilds(o.getMenuId(),menus, finalMapMenus));
            return menuTree;
        }).collect(Collectors.toList());
    }


    private List<MenuTree> getChilds(Long id,List<Menu> list,Map<Long, Long> mapMenus){
        return list.stream().filter(o -> o.getParentId().equals(id) ).map(o -> {
            MenuTree menuTree = new MenuTree();
            menuTree.setId(o.getMenuId());
            menuTree.setPid(o.getParentId());
            menuTree.setUrl(o.getUrl());
            menuTree.setChecked(mapMenus.get(o.getMenuId()) != null);
            menuTree.setName(o.getMenuName());
            menuTree.setBtoType(o.getType());
            menuTree.setChild(getChilds(o.getMenuId(), list, mapMenus));
            return menuTree;
        }).collect(Collectors.toList());
    }

    /**
     * <p>
     *     获取子集
     * </p>
     * @param id
     * @param list
     * @param mapMenus
     * @return
     */
    private List<MenuTree> getChild(Long id,List<Menu> list,Map<Long, Long> mapMenus){
       return list.stream().filter(o -> o.getParentId().equals(id) && o.getType() == 2).map(o -> {
            MenuTree menuTree = new MenuTree();
            menuTree.setId(o.getMenuId());
            menuTree.setPid(o.getParentId());
            menuTree.setUrl(o.getUrl());
            menuTree.setChecked(mapMenus.get(o.getMenuId()) != null);
            menuTree.setName(o.getMenuName());
            menuTree.setBtoType(o.getType());
            menuTree.setChild(getChild(o.getMenuId(), list, mapMenus));
            return menuTree;
        }).collect(Collectors.toList());
    }

    @Override
    public List<MenuTree> getRolePerssions(List<Long> roleId) {
        if (null == roleId || roleId.size() == 0){
            return Lists.newArrayList();
        }
        LambdaQueryWrapper<Menu> eq = new QueryWrapper<Menu>().lambda().eq(Menu::getMenuStatus, 1);
        eq.orderByAsc(Menu::getSort);
        //查询所有，有效菜单。
        List<Menu> menus = menuDao.selectList(eq);
        if (null == menus || menus.size() == 0){
            return Lists.newArrayList();
        }
        LambdaQueryWrapper<RoleMenu> roleMenuQueryWrapper = new QueryWrapper<RoleMenu>().lambda();
        roleMenuQueryWrapper.in(RoleMenu::getRoleId,roleId);

        List<RoleMenu> roleMenus = roleMenuDao.selectList(roleMenuQueryWrapper);
        Map<Long, Long> mapMenus = new HashMap<>(16);
        if (null != roleMenus && roleMenus.size() >0){
            mapMenus = roleMenus.stream().collect(Collectors.toMap(RoleMenu::getMenuId, RoleMenu::getRoleId, (k1, k2) -> k1));
        }
        Map<Long, Long> finalMapMenus = mapMenus;
        return  menus.stream().filter(o->o.getParentId().equals(0L)).map(o->{
            MenuTree menuTree = new MenuTree();
            menuTree.setId(o.getMenuId());
            menuTree.setPid(o.getParentId());
            menuTree.setUrl(o.getUrl());
            menuTree.setName(o.getMenuName());
            menuTree.setBtoType(o.getType());
            menuTree.setChecked(finalMapMenus.get(o.getMenuId()) != null);
            menuTree.setChild(getChild(o.getMenuId(),menus, finalMapMenus));
            return menuTree;
        }).collect(Collectors.toList());
    }
}
